/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package ms.jasim.model.event.impl;

import ms.jasim.framework.IJasimAppContext;
import ms.jasim.framework.SolutionSimulator.SimulatorArg;
import ms.jasim.model.JasimModel;
import ms.jasim.model.event.Event;
import ms.jasim.model.event.EventPackage;
import ms.jasim.model.event.EventPrecondition;
import ms.jasim.model.event.EventReaction;
import ms.jasim.model.event.ReactionList;
import ms.jasim.model.impl.NamedModelObjectImpl;
import ms.jasim.model.items.Item;
import ms.jasim.model.items.ItemList;
import ms.jasim.model.items.impl.ItemListImpl;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Event</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link ms.jasim.model.event.impl.EventImpl#getPrecondition <em>Precondition</em>}</li>
 *   <li>{@link ms.jasim.model.event.impl.EventImpl#getParameters <em>Parameters</em>}</li>
 *   <li>{@link ms.jasim.model.event.impl.EventImpl#getPostcondition <em>Postcondition</em>}</li>
 *   <li>{@link ms.jasim.model.event.impl.EventImpl#isEnabled <em>Enabled</em>}</li>
 *   <li>{@link ms.jasim.model.event.impl.EventImpl#isHappenOnce <em>Happen Once</em>}</li>
 *   <li>{@link ms.jasim.model.event.impl.EventImpl#getLabel <em>Label</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class EventImpl extends NamedModelObjectImpl implements Event {
	/**
	 * The cached value of the '{@link #getPrecondition() <em>Precondition</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPrecondition()
	 * @generated
	 * @ordered
	 */
	protected EventPrecondition precondition;

	/**
	 * The cached value of the '{@link #getParameters() <em>Parameters</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getParameters()
	 * @generated
	 * @ordered
	 */
	protected ItemList parameters;

	/**
	 * The cached value of the '{@link #getPostcondition() <em>Postcondition</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPostcondition()
	 * @generated
	 * @ordered
	 */
	protected ReactionList postcondition;

	/**
	 * The default value of the '{@link #isEnabled() <em>Enabled</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isEnabled()
	 * @generated
	 * @ordered
	 */
	protected static final boolean ENABLED_EDEFAULT = true;

	/**
	 * The cached value of the '{@link #isEnabled() <em>Enabled</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isEnabled()
	 * @generated
	 * @ordered
	 */
	protected boolean enabled = ENABLED_EDEFAULT;

	/**
	 * The default value of the '{@link #isHappenOnce() <em>Happen Once</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHappenOnce()
	 * @generated
	 * @ordered
	 */
	protected static final boolean HAPPEN_ONCE_EDEFAULT = true;

	/**
	 * The cached value of the '{@link #isHappenOnce() <em>Happen Once</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHappenOnce()
	 * @generated
	 * @ordered
	 */
	protected boolean happenOnce = HAPPEN_ONCE_EDEFAULT;

	/**
	 * The default value of the '{@link #getLabel() <em>Label</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLabel()
	 * @generated
	 * @ordered
	 */
	protected static final String LABEL_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getLabel() <em>Label</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLabel()
	 * @generated
	 * @ordered
	 */
	protected String label = LABEL_EDEFAULT;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	protected EventImpl() {
		super();
		setParameters(new ItemListImpl());
		setPostcondition(new ReactionListImpl());
		
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return EventPackage.Literals.EVENT;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EventPrecondition getPrecondition() {
		return precondition;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetPrecondition(EventPrecondition newPrecondition, NotificationChain msgs) {
		EventPrecondition oldPrecondition = precondition;
		precondition = newPrecondition;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, EventPackage.EVENT__PRECONDITION, oldPrecondition, newPrecondition);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setPrecondition(EventPrecondition newPrecondition) {
		if (newPrecondition != precondition) {
			NotificationChain msgs = null;
			if (precondition != null)
				msgs = ((InternalEObject)precondition).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - EventPackage.EVENT__PRECONDITION, null, msgs);
			if (newPrecondition != null)
				msgs = ((InternalEObject)newPrecondition).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - EventPackage.EVENT__PRECONDITION, null, msgs);
			msgs = basicSetPrecondition(newPrecondition, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EventPackage.EVENT__PRECONDITION, newPrecondition, newPrecondition));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ItemList getParameters() {
		return parameters;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public NotificationChain basicSetParameters(ItemList newParameters, NotificationChain msgs) {
		ItemList oldParameters = parameters;
		parameters = newParameters;
		parameters.setName("Parameters");
		parameters.setPredefined(true);
		
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, EventPackage.EVENT__PARAMETERS, oldParameters, newParameters);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setParameters(ItemList newParameters) {
		if (newParameters != parameters) {
			NotificationChain msgs = null;
			if (parameters != null)
				msgs = ((InternalEObject)parameters).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - EventPackage.EVENT__PARAMETERS, null, msgs);
			if (newParameters != null)
				msgs = ((InternalEObject)newParameters).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - EventPackage.EVENT__PARAMETERS, null, msgs);
			msgs = basicSetParameters(newParameters, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EventPackage.EVENT__PARAMETERS, newParameters, newParameters));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ReactionList getPostcondition() {
		return postcondition;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public NotificationChain basicSetPostcondition(ReactionList newPostcondition, NotificationChain msgs) {
		ReactionList oldPostcondition = postcondition;
		postcondition = newPostcondition;
		postcondition.setName("Post Conditions");
		postcondition.setPredefined(true);
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, EventPackage.EVENT__POSTCONDITION, oldPostcondition, newPostcondition);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setPostcondition(ReactionList newPostcondition) {
		if (newPostcondition != postcondition) {
			NotificationChain msgs = null;
			if (postcondition != null)
				msgs = ((InternalEObject)postcondition).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - EventPackage.EVENT__POSTCONDITION, null, msgs);
			if (newPostcondition != null)
				msgs = ((InternalEObject)newPostcondition).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - EventPackage.EVENT__POSTCONDITION, null, msgs);
			msgs = basicSetPostcondition(newPostcondition, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EventPackage.EVENT__POSTCONDITION, newPostcondition, newPostcondition));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isEnabled() {
		return enabled;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setEnabled(boolean newEnabled) {
		boolean oldEnabled = enabled;
		enabled = newEnabled;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EventPackage.EVENT__ENABLED, oldEnabled, enabled));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isHappenOnce() {
		return happenOnce;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHappenOnce(boolean newHappenOnce) {
		boolean oldHappenOnce = happenOnce;
		happenOnce = newHappenOnce;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EventPackage.EVENT__HAPPEN_ONCE, oldHappenOnce, happenOnce));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getLabel() {
		return label;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setLabel(String newLabel) {
		String oldLabel = label;
		label = newLabel;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EventPackage.EVENT__LABEL, oldLabel, label));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public boolean isChangable() {
		return false;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public boolean react(IJasimAppContext context, JasimModel model) {
		boolean replan = false;
		IJasimAppContext childContext = context.createChildContext("");
		childContext.addService(getPrecondition());
		
		for (EventReaction reaction: getPostcondition().getReaction())
			replan |= reaction.react(childContext, model, this);
		return replan;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public Object getParameterValue(IJasimAppContext context, String paramName) {
		Item item = this.getParameters().get(paramName);
		return item != null ? item.getValue(context) : null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case EventPackage.EVENT__PRECONDITION:
				return basicSetPrecondition(null, msgs);
			case EventPackage.EVENT__PARAMETERS:
				return basicSetParameters(null, msgs);
			case EventPackage.EVENT__POSTCONDITION:
				return basicSetPostcondition(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case EventPackage.EVENT__PRECONDITION:
				return getPrecondition();
			case EventPackage.EVENT__PARAMETERS:
				return getParameters();
			case EventPackage.EVENT__POSTCONDITION:
				return getPostcondition();
			case EventPackage.EVENT__ENABLED:
				return isEnabled();
			case EventPackage.EVENT__HAPPEN_ONCE:
				return isHappenOnce();
			case EventPackage.EVENT__LABEL:
				return getLabel();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case EventPackage.EVENT__PRECONDITION:
				setPrecondition((EventPrecondition)newValue);
				return;
			case EventPackage.EVENT__PARAMETERS:
				setParameters((ItemList)newValue);
				return;
			case EventPackage.EVENT__POSTCONDITION:
				setPostcondition((ReactionList)newValue);
				return;
			case EventPackage.EVENT__ENABLED:
				setEnabled((Boolean)newValue);
				return;
			case EventPackage.EVENT__HAPPEN_ONCE:
				setHappenOnce((Boolean)newValue);
				return;
			case EventPackage.EVENT__LABEL:
				setLabel((String)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case EventPackage.EVENT__PRECONDITION:
				setPrecondition((EventPrecondition)null);
				return;
			case EventPackage.EVENT__PARAMETERS:
				setParameters((ItemList)null);
				return;
			case EventPackage.EVENT__POSTCONDITION:
				setPostcondition((ReactionList)null);
				return;
			case EventPackage.EVENT__ENABLED:
				setEnabled(ENABLED_EDEFAULT);
				return;
			case EventPackage.EVENT__HAPPEN_ONCE:
				setHappenOnce(HAPPEN_ONCE_EDEFAULT);
				return;
			case EventPackage.EVENT__LABEL:
				setLabel(LABEL_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case EventPackage.EVENT__PRECONDITION:
				return precondition != null;
			case EventPackage.EVENT__PARAMETERS:
				return parameters != null;
			case EventPackage.EVENT__POSTCONDITION:
				return postcondition != null;
			case EventPackage.EVENT__ENABLED:
				return enabled != ENABLED_EDEFAULT;
			case EventPackage.EVENT__HAPPEN_ONCE:
				return happenOnce != HAPPEN_ONCE_EDEFAULT;
			case EventPackage.EVENT__LABEL:
				return LABEL_EDEFAULT == null ? label != null : !LABEL_EDEFAULT.equals(label);
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (Enabled: ");
		result.append(enabled);
		result.append(", HappenOnce: ");
		result.append(happenOnce);
		result.append(", Label: ");
		result.append(label);
		result.append(')');
		return result.toString();
	}

	@Override
	public boolean canTriggerNow(IJasimAppContext context, SimulatorArg arg) {
		if (getPrecondition() != null) {
			return getPrecondition().conditionMatch(context, arg);
		}
		return false;
	}
} //EventImpl
